﻿using System;

namespace MyBasicLib.Collections.Generic
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class GenericPool<T> where T : class
    {
        private readonly T[] _list;
        private int _availableIndex;
        //public static readonly GenericPool<T> Default = new GenericPool<T>();
        //public GenericPool() : this(8, false)
        //{
        //}

        public GenericPool(int capacity = 8)
        {
            Capacity = capacity;
            _availableIndex = 0;
            _list = new T[capacity];
        }

        public int Count
        {
            get { return _availableIndex; }
        }

        public int Capacity { get; private set; }

        public T GetPoolObject(Func<T> creator)
        {
            if (_availableIndex > 0)
            {
                return _list[--_availableIndex];
            }
            return creator();
        }

        public void ReturnPoolObject(T obj)
        {
            if (_availableIndex >= Capacity) return;
            _list[_availableIndex++] = obj;
        }
    }

    ///// <summary>
    ///// 
    ///// </summary>
    ///// <typeparam name="T"></typeparam>
    //public class GenericPool<T> where T : class
    //{
    //    private readonly T[] _list;
    //    private int _availableIndex;
    //    // public static readonly GenericPool<T> Default = new GenericPool<T>();
    //    //public GenericPool() : this(8, false)
    //    //{
    //    //}

    //    public GenericPool(int capacity = 8, bool threadSafe = false)
    //    {
    //        Capacity = capacity;
    //        IsThreadSafe = threadSafe;
    //        _availableIndex = 0;
    //        _list = new T[capacity];
    //    }

    //    public bool IsThreadSafe { get; private set; }

    //    public int Count
    //    {
    //        get { return _availableIndex; }
    //    }

    //    public int Capacity { get; private set; }

    //    public T GetPoolObject(Func<T> creator)
    //    {
    //        if (_availableIndex > 0)
    //        {
    //            if (!IsThreadSafe)
    //                return _list[--_availableIndex];
    //            lock (_list)
    //            {
    //                if (_availableIndex > 0)
    //                {
    //                    return _list[--_availableIndex];
    //                }
    //            }
    //        }
    //        return creator();
    //    }

    //    public void ReturnPoolObject(T obj)
    //    {
    //        if (_availableIndex >= Capacity) return;
    //        if (IsThreadSafe)
    //        {
    //            lock (_list)
    //            {
    //                if (_availableIndex >= Capacity) return;
    //                _list[_availableIndex++] = obj;
    //            }
    //        }
    //        else _list[_availableIndex++] = obj;
    //    }
    //}
}